home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Linux Cubed Series 7: Sunsite
/
Linux Cubed Series 7 - Sunsite Vol 1.iso
/
system
/
news
/
inn1.000
/
inn1.4sec-linux-src.tar
/
inn
/
frontends
/
decode.c
< prev
next >
Wrap
C/C++ Source or Header
|
1993-03-18
|
4KB
|
169 lines
/*
** Decode seven-bit input into full binary output.
** From @(#)decode.c 1.3 5/15/85, distributed with B2.11 News.
**
** Collect runs of 12 seven-bit characters. Combine them in pairs to
** make six 13-bit characters. Extract the top bit of each pair to make
** a 13th six-bit character, and split the remaining six 12-bit
** characters to form 12 six-bit characters. Collect four six-bit
** characters and convert it to three eight-bit characters.
**
** Got that? All the remaining work in this program is to get the
** ending conditions right.
*/
#include "configdata.h"
#include <stdio.h>
#include <sys/types.h>
#include "clibrary.h"
/*
** These characters can't appear in normal output, so we use them to
** mark that the data that follows is the terminator. The character
** immediately following this pair is the length of the terminator (which
** otherwise might be indeterminable)
*/
#define ENDMARK1 ((90 * 91 + 90) / 91)
#define ENDMARK2 ((90 * 91 + 90) % 91)
static char Buffer[4];
static int count;
static void
pack6(n, last)
register int n;
int last;
{
register char *q;
register int i;
char b3[3];
i = 3;
if (last && (i = Buffer[n - 1]) >= 3) {
/* Do the best we can. */
(void)fprintf(stderr, "Badly-terminated file.\n");
i = 3;
}
b3[0] = (Buffer[0] << 2) | ((Buffer[1] >> 4) & 0x03);
b3[1] = (Buffer[1] << 4) | ((Buffer[2] >> 2) & 0x0F);
b3[2] = (Buffer[2] << 6) | ( Buffer[3] & 0x3F);
for (q = b3; --i >= 0; )
(void)putchar(*q++);
}
static void
pack12(p, n, last)
register char *p;
register int n;
int last;
{
register char *q;
register int c13;
register int c;
register int i;
char b13[13];
char b3[3];
for (q = b13, c13 = 0, i = 0; i < n; i += 2) {
c = *p++ * 91;
c += *p++;
c13 <<= 1;
if (c & (1 << 12))
c13 |= 1;
*q++ = (c >> 6) & 0x3F;
*q++ = c & 0x3F;
}
*q++ = (char)c13;
if (last)
q = &b13[last];
for (p = b13, n = q - p, i = count, q = &Buffer[count]; --n > 0; ) {
*q++ = *p++;
if (++i == 4) {
/* Inline expansion of pack6. */
b3[0] = (Buffer[0] << 2) | ((Buffer[1] >> 4) & 0x03);
b3[1] = (Buffer[1] << 4) | ((Buffer[2] >> 2) & 0x0F);
b3[2] = (Buffer[2] << 6) | ( Buffer[3] & 0x3F);
(void)putchar(b3[0]);
(void)putchar(b3[1]);
(void)putchar(b3[2]);
i = 0;
q = Buffer;
}
}
/* The last octet. */
*q++ = *p++;
i++;
if (last || i == 4) {
pack6(i, last);
i = 0;
}
count = i;
}
/* ARGSUSED0 */
int
main(ac, av)
int ac;
char *av[];
{
register int c;
register char *p;
register int i;
register int first;
register int cnt;
char *base;
char b12[12];
char c12[12];
base = p = b12;
for (i = 12, cnt = 0, first = 1; (c = getchar()) != EOF; ) {
if (c < ' ' || c >= ' ' + 91) {
(void)fprintf(stderr, "decode: Bad data\n");
exit(1);
}
if (i == 10 && p[-1] == ENDMARK1 && p[-2] == ENDMARK2) {
cnt = c - ' ';
i = 12;
p -= 2;
continue;
}
*p++ = c - ' ';
if (--i == 0) {
if (p == &b12[12]) {
if (!first)
pack12(c12, 12, 0);
else
first = 0;
base = p = c12;
}
else {
pack12(b12, 12, 0);
base = p = b12;
}
i = 12;
}
}
if (base == b12) {
if (!first)
pack12(c12, 12, i == 12 ? cnt : 0);
}
else
pack12(b12, 12, i == 12 ? cnt : 0);
if (i != 12)
pack12(base, 12 - i, cnt);
exit(0);
/* NOTREACHED */
}